<?php

namespace app\api\service;

use app\admin\model\AttentionFactor;
use app\admin\model\AttentionQuestionnaire;
use app\admin\model\AttentionSetting;
use app\admin\model\AttentionUser;
use app\admin\model\AttentionUserData;
use app\admin\model\AttentionResult;
use DateTime;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\HttpException;
use think\Exception;

/**
 * 部门管理-服务类
 * Class DeptService
 * @package app\admin\service
 */
class AttentionService extends BaseService
{
    /**
     * 构造函数
     *
     * DeptService constructor.
     */
    protected $settingModel;
    protected $userDataModel;
    protected $userModel;
    protected $questionModel;
    protected $factorModel;
    protected $resultModel;
    public function __construct()
    {
        $this->settingModel = new AttentionSetting();
        $this->userDataModel = new AttentionUserData();
        $this->userModel = new AttentionUser();
        $this->questionModel = new AttentionQuestionnaire();
        $this->factorModel = new AttentionFactor();
        $this->resultModel = new AttentionResult();
        parent::__construct();
    }

    public function init()
    {
        try {

            $setting = $this->settingModel->getInfo(1);
            return $this->success(['is_enable' => (int)$setting['is_enable'], 'description' => $setting['description'], 'need_pwd' => (bool)!empty($setting['access_pwd'])]);

        } catch (Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    public function checkPwd()
    {
        try {
            $params = request()->param();
            $password = getter($params, 'password', '');
            if (empty($password)) throw new Exception('请输入密码');

            $setting = $this->settingModel->getInfo(1);
            if ($setting['access_pwd'] != $password) throw new Exception('密码验证失败，无法继续进行');

            return $this->success();

        } catch (Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    public function list()
    {
        try {

            $list = $this->questionModel->getList([], 'id asc');
            foreach ($list as &$item) {
                unset($item['options']);
                unset($item['create_time']);
                unset($item['create_user']);
                unset($item['update_time']);
                unset($item['update_user']);
                unset($item['remark']);
                unset($item['mark']);
                $item['answer'] = null;
            }
            return $this->success($list);
        } catch (Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    public function answer()
    {
        try {

            $params = request()->param();
            $userId = getter($params, 'user_id', '');
            if (empty($userId)) throw new Exception('参数错误');
            $user = $this->userModel->getInfo($userId);
            if (empty($user)) throw new Exception('数据异常');

            $questionId = getter($params, 'question_id', '');
            if (empty($questionId)) throw new Exception('question param error');
            $question = $this->questionModel->getInfo($questionId);
            if (empty($question)) throw new Exception('未知问题');

            $answerIndex = getter($params, 'answer_index', '');
            if (!isset($answerIndex)) throw new Exception('answer param error');
            $answer = $question['format_options'][$answerIndex] ?? [];
            if (empty($answer)) throw new Exception('非法选项');

            $data = [
                'user_id' => $userId,
                'question_id' => $questionId,
                'question_type' => $question['question_type'],
                'question' => $question['question'],
                'answer_text' => $answer->label,
                'answer_score' => $answer->value
            ];

            $exist = $this->userDataModel->where(['user_id' => $userId, 'question_id' => $questionId])->find();
            if (!empty($exist)) {
                $save = $this->userDataModel->save($data, ['id' => $exist['id']]);
            } else {
                $save = $this->userDataModel->edit($data);
            }

            if (!$save) throw new Exception('保存失败');
            return $this->success();
        } catch (Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    public function submit()
    {
        try {
            $params = request()->param();
            $userId = getter($params, 'user_id', '');
            if (empty($userId)) throw new Exception('参数错误');
            $user = $this->userModel->getInfo($userId);
            if (empty($user)) throw new Exception('数据异常');

            $answers = getter($params, 'answers', []);
            if (empty($answers)) throw new Exception('参数错误');

            foreach($answers as $answer) {
                $questionId = getter($answer, 'question_id', '');
                if (empty($questionId)) throw new Exception('question param error');
                $question = $this->questionModel->getInfo($questionId);
                if (empty($question)) throw new Exception('未知问题');

                $answerIndex = $answer['answer_index'];
                if (!isset($answerIndex)) throw new Exception('answer param error');
                $answer = $question['format_options'][$answerIndex] ?? [];
                if (empty($answer)) throw new Exception('非法选项');

                $data = [
                    'user_id' => $userId,
                    'question_id' => $questionId,
                    'question_type' => $question['question_type'],
                    'question' => $question['question'],
                    'answer_index' => $answerIndex,
                    'answer_text' => $answer->label,
                    'answer_score' => $answer->value
                ];

                $exist = $this->userDataModel->where(['user_id' => $userId, 'question_id' => $questionId])->find();
                if (!empty($exist)) {
                    $data['id'] = $exist['id'];
                }
                $save = $this->userDataModel->edit($data);

                if (!$save) throw new Exception('保存失败');
            }

            // 更新用户完成情况
            $updateUser = $this->userModel->edit(['id' => $userId, 'is_finish' => 1, 'finish_time' => time()]);
            if (!$updateUser) throw new Exception('数据提交失败');

            return $this->success();
        } catch (Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    public function getResult()
    {
        try {

            $params = request()->param();
            $userId = getter($params, 'user_id', '');
            if (empty($userId)) throw new Exception('参数错误');
            $user = $this->userModel->getInfo($userId);
            if (empty($user)) throw new Exception('数据异常');

            $answers = $this->userDataModel->where('user_id', $userId)->select();
            $answerScore = [];
            foreach ($answers as $k => $answer) {
                $answerScore[] = $answer['answer_score'];
            }
            $totalScore = array_sum($answerScore);

            $setting = $this->settingModel->getInfo(1);
            $unusual = $totalScore >= $setting['warning_score'];


            $factors = $this->factorModel->where('mark', 1)->order('weight', 'desc')->select();
            $data = [];
            $resData = [];
            foreach ($factors as $factor) {
                $calcRule = json_decode($factor['calc_rule'], true);
                $factorAnswerScore = $this->calcScoreByFactor($answers, $factor['id']);
                $result = $this->calcResultByFactorScore($factorAnswerScore, $calcRule);
                $data[] = [
                    'title' => $factor['title'],
                    'tips' => $factor['tips'],
                    'desc' => $factor['desc'],
                    'score' => $factorAnswerScore,
                    'result' => $result['result'],
                    'result_desc' => $result['desc']
                ];
                $resData[] = [
                    'user_id' => $userId,
                    'question_type' => $factor['id'],
                    'total_score' => $factorAnswerScore,
                    'result' => $result['result'],
                    'result_desc' => $result['desc']
                ];
            }

            $result = [
                'total_score' => $totalScore,
                'is_unusual' => $unusual,
                'warning_text' => $setting['warning_text'],
                'data' => $data
            ];

            // 更新结果数据
            if ($user['is_finish'] == 1) {
                $this->resultModel->doDelete(['user_id' => $userId]);
                array_unshift($resData, [
                    'user_id' => $userId,
                    'question_type' => 0, // 0代表总分
                    'total_score' => $totalScore,
                    'result' => $unusual ? '异常' : '正常',
                    'result_desc' => $unusual ? $setting['warning_text'] : ''
                ]);
                $insert = $this->resultModel->saveAll($resData);
                if (!$insert) throw new Exception('数据信息同步失败');
            }

            return $this->success($result);
        } catch (Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    private function calcScoreByFactor($answers, $factorId)
    {
        $scores = [];
        if (!empty($answers)) {
            foreach ($answers as $answer) {
                if ($answer['question_type'] == $factorId) {
                    $scores[] = $answer['answer_score'];
                }
            }
        }
        return array_sum($scores);
    }

    private function calcResultByFactorScore($score, $rule)
    {
        foreach ($rule as $item) {
            if ($score >= $item['min'] && $score <= $item['max']) {
                return $item;
                break;
            }
        }
        return [];
    }
}